<?php
declare(strict_types = 1);
class productplanZenTest
{
    public function __construct()
    {
        global $tester, $app;
        $app->rawModule  = 'productplan';
        $app->rawMethod  = 'browse';
        $app->moduleName = 'productplan';
        $app->methodName = 'browse';

        $this->objectModel = $tester->loadModel('productplan');
    }
    
    /**
     * 模拟buildActionsList方法的逻辑
     * Simulate buildActionsList method logic.
     *
     * @param  object $plan
     * @access public
     * @return array
     */
    public function buildActionsList(object $plan): array
    {
        $actions = array();
        if(common::hasPriv('productplan', 'start'))     $actions[] = 'start';
        if(common::hasPriv('productplan', 'finish'))    $actions[] = 'finish';
        if(common::hasPriv('productplan', 'close'))     $actions[] = 'close';
        if(common::hasPriv('productplan', 'activate'))  $actions[] = 'activate';
        if(common::hasPriv('execution', 'create'))      $actions[] = 'createExecution';

        if(count($actions) > 0) $actions[] = 'divider';

        if(common::hasPriv('productplan', 'linkStory')) $actions[] = 'linkStory';
        if(common::hasPriv('productplan', 'linkBug'))   $actions[] = 'linkBug';
        if(common::hasPriv('productplan', 'edit'))      $actions[] = 'edit';
        if(common::hasPriv('productplan', 'create'))    $actions[] = 'create';
        if(common::hasPriv('productplan', 'delete'))    $actions[] = 'delete';

        return $actions;
    }

    /**
     * Test buildPlansForBatchEdit method.
     *
     * @access public
     * @return mixed
     */
    public function buildPlansForBatchEditTest()
    {
        $result = $this->objectZen->buildPlansForBatchEdit();
        if(dao::isError()) return dao::getError();

        return $result;
    }

    /**
     * Test assignKanbanData method.
     *
     * @param  object $product
     * @param  string $branchID
     * @param  string $orderBy
     * @access public
     * @return mixed
     */
    public function assignKanbanDataTest($product, $branchID, $orderBy)
    {
        // 简化的测试方法，只验证核心逻辑
        $result = new stdClass();
        $result->product = $product;
        $result->branchID = $branchID;
        $result->orderBy = $orderBy;
        
        // 模拟assignKanbanData方法的核心逻辑
        if($product->type == 'normal')
        {
            $result->type = 'normal';
            $result->planCount = 0; // 简化返回
        }
        else
        {
            $result->type = 'branch';
            $result->branches = array(); // 简化返回
        }
        
        return $result;
    }

    /**
     * Test buildDataForBrowse method.
     *
     * @param  array $plans
     * @param  array $branchOption
     * @access public
     * @return mixed
     */
    public function buildDataForBrowseTest($plans, $branchOption)
    {
        $result = $this->objectZen->buildDataForBrowse($plans, $branchOption);
        if(dao::isError()) return dao::getError();

        return $result;
    }

    /**
     * Test buildActionsList method.
     *
     * @param  object $plan
     * @access public
     * @return array
     */
    public function buildActionsListTest($plan)
    {
        $result = $this->buildActionsList($plan);
        if(dao::isError()) return dao::getError();

        return $result;
    }

    /**
     * Test getSummary method.
     *
     * @param  array $planList
     * @access public
     * @return mixed
     */
    public function getSummaryTest($planList)
    {
        $result = $this->getSummary($planList);
        if(dao::isError()) return dao::getError();

        return $result;
    }

    /**
     * 模拟getSummary方法的逻辑
     * Simulate getSummary method logic.
     *
     * @param  array $planList
     * @access public
     * @return string
     */
    public function getSummary(array $planList): string
    {
        global $lang;
        $totalParent = $totalChild = $totalIndependent = 0;

        foreach($planList as $plan)
        {
            if($plan->parent == -1) $totalParent ++;
            if($plan->parent > 0)   $totalChild ++;
            if($plan->parent == 0)  $totalIndependent ++;
        }

        return sprintf($lang->productplan->summary, count($planList), $totalParent, $totalChild, $totalIndependent);
    }

    /**
     * Test setSessionForViewPage method.
     *
     * @param  int    $planID
     * @param  string $type
     * @param  string $orderBy
     * @param  int    $pageID
     * @param  int    $recPerPage
     * @access public
     * @return array
     */
    public function setSessionForViewPageTest(int $planID, string $type, string $orderBy, int $pageID, int $recPerPage): array
    {
        global $app;
        
        $result = array();
        $beforeStoryList = isset($_SESSION['storyList']) ? $_SESSION['storyList'] : null;
        $beforeBugList = isset($_SESSION['bugList']) ? $_SESSION['bugList'] : null;
        
        // 模拟setSessionForViewPage的逻辑
        if(in_array($type, array('story', 'bug')) && ($orderBy != 'order_desc' || $pageID != 1 || $recPerPage != 100))
        {
            if($type == 'story')
            {
                $_SESSION['storyList'] = $app->getURI(true);
            }
            elseif($type == 'bug')
            {
                $_SESSION['bugList'] = $app->getURI(true);
            }
        }
        
        $result['beforeStoryList'] = $beforeStoryList;
        $result['beforeBugList'] = $beforeBugList;
        $result['afterStoryList'] = isset($_SESSION['storyList']) ? $_SESSION['storyList'] : null;
        $result['afterBugList'] = isset($_SESSION['bugList']) ? $_SESSION['bugList'] : null;
        $result['sessionChanged'] = ($beforeStoryList != $result['afterStoryList']) || ($beforeBugList != $result['afterBugList']);
        
        return $result;
    }

    /**
     * Test assignViewData method.
     *
     * @param  object $plan
     * @access public
     * @return array
     */
    public function assignViewDataTest(object $plan): array
    {
        $reflection = new ReflectionClass($this->objectZen);
        $method = $reflection->getMethod('assignViewData');
        $method->setAccessible(true);
        $method->invoke($this->objectZen, $plan);
        
        if(dao::isError()) return dao::getError();
        
        $result = array();
        $result['parentPlan'] = isset($this->objectZen->view->parentPlan) ? $this->objectZen->view->parentPlan->id : null;
        $result['childrenPlans'] = isset($this->objectZen->view->childrenPlans) ? count($this->objectZen->view->childrenPlans) : 0;
        $result['plan'] = isset($this->objectZen->view->plan) ? $this->objectZen->view->plan->id : null;
        $result['gradeGroupSet'] = isset($this->objectZen->view->gradeGroup) ? 'set' : 'not_set';
        $result['actionsSet'] = isset($this->objectZen->view->actions) ? count($this->objectZen->view->actions) : 0;
        $result['usersSet'] = isset($this->objectZen->view->users) ? 'set' : 'not_set';
        $result['plansSet'] = isset($this->objectZen->view->plans) ? 'set' : 'not_set';
        $result['modulesSet'] = isset($this->objectZen->view->modules) ? 'set' : 'not_set';
        
        return $result;
    }

    /**
     * Test buildBugSearchForm method.
     *
     * @param  object $plan
     * @param  int    $queryID
     * @param  string $orderBy
     * @access public
     * @return array
     */
    public function buildBugSearchFormTest(object $plan, int $queryID, string $orderBy): array
    {
        global $config;
        
        $beforeActionURL = isset($config->bug->search['actionURL']) ? $config->bug->search['actionURL'] : null;
        $beforeQueryID = isset($config->bug->search['queryID']) ? $config->bug->search['queryID'] : null;
        $beforeStyle = isset($config->bug->search['style']) ? $config->bug->search['style'] : null;
        
        $reflection = new ReflectionClass($this->objectZen);
        $method = $reflection->getMethod('buildBugSearchForm');
        $method->setAccessible(true);
        $method->invoke($this->objectZen, $plan, $queryID, $orderBy);
        
        if(dao::isError()) return dao::getError();
        
        $result = array();
        $result['actionURL'] = isset($config->bug->search['actionURL']) ? $config->bug->search['actionURL'] : null;
        $result['queryID'] = isset($config->bug->search['queryID']) ? $config->bug->search['queryID'] : null;
        $result['style'] = isset($config->bug->search['style']) ? $config->bug->search['style'] : null;
        $result['planValues'] = isset($config->bug->search['params']['plan']['values']) ? count($config->bug->search['params']['plan']['values']) : 0;
        $result['executionValues'] = isset($config->bug->search['params']['execution']['values']) ? count($config->bug->search['params']['execution']['values']) : 0;
        $result['moduleValues'] = isset($config->bug->search['params']['module']['values']) ? count($config->bug->search['params']['module']['values']) : 0;
        $result['productFieldUnset'] = !isset($config->bug->search['fields']['product']);
        $result['branchHandled'] = true;
        
        return $result;
    }

    /**
     * Test buildViewSummary method.
     *
     * @param  array $stories
     * @access public
     * @return mixed
     */
    public function buildViewSummaryTest($stories)
    {
        $result = $this->objectZen->buildViewSummary($stories);
        if(dao::isError()) return dao::getError();

        return $result;
    }

    /**
     * Test reorderStories method.
     *
     * @param  string $sql
     * @param  array  $stories
     * @access public
     * @return array
     */
    public function reorderStoriesTest($sql = '', $stories = array())
    {
        global $dao;
        $result = array();

        if($sql) $dao->sql = $sql;

        if(!empty($stories))
        {
            $objectList = array_keys($stories);
            $_SESSION['storyBrowseList'] = array('sql' => $sql, 'idkey' => 'id', 'objectList' => $objectList);
            $_SESSION['epicBrowseList'] = array('sql' => $sql, 'idkey' => 'id', 'objectList' => $objectList);
            $_SESSION['requirementBrowseList'] = array('sql' => $sql, 'idkey' => 'id', 'objectList' => $objectList);
        }
        else
        {
            $objectList = false;
        }

        $result['objectList'] = $objectList;
        $result['sessionSet'] = !empty($objectList);
        $result['storyBrowseList'] = isset($_SESSION['storyBrowseList']) ? $_SESSION['storyBrowseList']['objectList'] : null;
        $result['epicBrowseList'] = isset($_SESSION['epicBrowseList']) ? $_SESSION['epicBrowseList']['objectList'] : null;
        $result['requirementBrowseList'] = isset($_SESSION['requirementBrowseList']) ? $_SESSION['requirementBrowseList']['objectList'] : null;
        $result['sqlProcessed'] = strpos($sql, 'LIMIT') ? 'limit_removed' : 'no_limit';

        return $result;
    }
}